import React, { PureComponent } from 'react';
import { DatePicker } from 'antd';
import moment from 'moment';
import 'moment/locale/zh-cn';
import styles from './index.less';

moment.locale('zh-cn');

const { RangePicker } = DatePicker;

const texts = ['昨日', '今日', '上周', '本周', '上月', '本月', '去年', '本年', '过去7天', '过去30天', '上线至今'];
const dateRanges = {
  昨日: [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
  今日: [moment(), moment()],
  上周: [
    moment()
      .startOf('week')
      .subtract(7, 'days'),
    moment()
      .startOf('week')
      .subtract(1, 'days')
  ],
  本周: [moment().startOf('week'), moment()],
  上月: [
    moment()
      .startOf('month')
      .subtract(1, 'months'),
    moment()
      .startOf('month')
      .subtract(1, 'days')
  ],
  本月: [moment().startOf('month'), moment()],
  去年: [
    moment()
      .startOf('year')
      .subtract(1, 'years'),
    moment()
      .startOf('year')
      .subtract(1, 'days')
  ],
  本年: [moment().startOf('year'), moment()],
  过去7天: [moment().subtract(7, 'days'), moment().subtract(1, 'days')],
  过去30天: [moment().subtract(30, 'days'), moment().subtract(1, 'days')],
  上线至今: [moment('2019-03-01', 'YYYY-MM-DD'), moment()]
};

const getRangeText = (dateStrings, ranges = dateRanges) => {
  let rangeText = '';
  const [start, end] = dateStrings;
  for (let i = 0; i < texts.length; i += 1) {
    const text = texts[i];
    const [theStart, theEnd] = ranges[text];
    const left = theStart.format('YYYY-MM-DD');
    const right = theEnd.format('YYYY-MM-DD');
    if (left === start && right === end) {
      rangeText = text;
      break;
    }
  }
  if (!rangeText) {
    const theStart = moment(start, 'YYYY-MM-DD');
    const theEnd = moment(end, 'YYYY-MM-DD');
    const daymax = moment().diff(theStart, 'days');
    const daymin = moment().diff(theEnd, 'days');
    if (daymin === 0) {
      rangeText = `最近${daymax + 1}天`;
    } else if (daymin === 1) {
      rangeText = `过去${daymax}天`;
    } else {
      rangeText = `过去${daymin}天 - 过去${daymax}天`;
    }
  }
  return rangeText;
};

const getDateRange = (rangeText, ranges = dateRanges) => {
  let fromDate;
  let toDate;
  const rangeKeys = Object.keys(ranges);
  if (rangeKeys.includes(rangeText)) {
    return dateRanges[rangeText];
  }
  if (/^最近\s*(\d+)\s*天$/.test(rangeText)) {
    const strDays = rangeText.replace(/最近\s*(\d+)\s*天/, '$1');
    const days = Number(strDays) - 1;
    fromDate = moment().subtract(days, 'days');
    toDate = moment();
    return [fromDate, toDate];
  }
  if (/^过去\s*(\d+)\s*天$/.test(rangeText)) {
    const strDays = rangeText.replace(/过去\s*(\d+)\s*天/, '$1');
    const days = Number(strDays);
    fromDate = moment().subtract(days, 'days');
    toDate = moment().subtract(1, 'days');
    return [fromDate, toDate];
  }
  if (/^过去\s*(\d+)\s*天\s*-\s*过去\s*(\d+)\s*天$/.test(rangeText)) {
    const matchs = rangeText.match(/过去\s*(\d+)\s*天\s*-\s*过去\s*(\d+)\s*天/);
    fromDate = moment().subtract(Number(matchs[2]), 'days');
    toDate = moment().subtract(Number(matchs[1]), 'days');
    return [fromDate, toDate];
  }
  return dateRanges['本周'];
};

class DateRangePicker extends PureComponent {
  static getDerivedStateFromProps(props, state) {
    // Should be a controlled component.
    const mt = moment();
    const iValue = [mt, mt];
    const { value = iValue } = props;
    const { selectValue = iValue } = state;
    const [pStart, pEnd] = value;
    const [sStart, sEnd] = selectValue;
    if (props.value && (pStart.diff(sStart) || pEnd.diff(sEnd))) {
      if (!value[2]) {
        const start = value[0].format('YYYY-MM-DD');
        const end = value[1].format('YYYY-MM-DD');
        value[2] = getRangeText([start, end], dateRanges);
      }
      return { value, selectValue: value };
    }
    return null;
  }

  state = {
    value: [],
    selectValue: [],
    showPopup: false
  };

  componentDidMount() {
    const { value } = this.state;
    this.setState({ selectValue: value });
  }

  handleRangeClick = e => {
    const rangeText = e.target.innerText;
    const { ranges = dateRanges } = this.props;
    const selectValue = [...ranges[rangeText], rangeText];
    this.setState({ value: selectValue, selectValue, showPopup: false });
    const { onChange } = this.props;
    if (onChange) {
      const dateStrings = [selectValue[0].format('YYYY-MM-DD'), selectValue[1].format('YYYY-MM-DD')];
      onChange(selectValue, dateStrings);
    }
  };

  handleChange = (dates, dateStrings) => {
    const { onChange, ranges = dateRanges } = this.props;
    const rangeText = getRangeText(dateStrings, ranges);
    const value = [...dates, rangeText];
    this.setState({ value });
    if (onChange) onChange(value, dateStrings);
  };

  onOpenChange = status => {
    if (status) {
      this.setState({ showPopup: status });
    } else {
      const { value, selectValue = [] } = this.state;
      const setObj = { showPopup: status };
      if (value !== selectValue) {
        setObj.value = selectValue;
      }
      this.setState(setObj);
    }
  };

  onPreviewHandler = text => {
    const { ranges = dateRanges } = this.props;
    const value = [...ranges[text], text];
    this.setState({ value });
  };

  offPreviewHandler = () => {
    const { value, selectValue } = this.state;
    if (value !== selectValue) {
      this.setState({ value: selectValue });
    }
  };

  renderExtraFooter = () => {
    const { ranges = dateRanges } = this.props;
    const rangeKeys = Object.keys(ranges);
    const { value = [] } = this.state;
    const rangeText = value[2];
    return (
      <>
        <div className={styles.rangeText}>{rangeText}</div>
        <div className={styles.relativeTime} onMouseLeave={() => this.offPreviewHandler()}>
          {rangeKeys.map(text => (
            <span
              key={text}
              className={`ant-tag${rangeText === text ? ' checked' : ''}`}
              onClick={e => this.handleRangeClick(e)}
              onMouseOver={() => this.onPreviewHandler(text)}
              onFocus={() => false}
              onBlur={() => false}
            >
              {text}
            </span>
          ))}
        </div>
      </>
    );
  };

  render() {
    const { validDateRange = [moment('2020-01-01', 'YYYY-MM-DD'), moment()] } = this.props;
    const { value, showPopup } = this.state;
    const $value = value ? [value[0], value[1]] : null;
    return (
      <div className={styles.allbox}>
        <RangePicker
          allowClear={false}
          separator="至"
          format="YYYY-MM-DD"
          {...this.props}
          value={$value}
          onChange={this.handleChange}
          dropdownClassName={styles.dateDropBox}
          renderExtraFooter={this.renderExtraFooter}
          open={showPopup}
          // ranges={dateRanges}
          getCalendarContainer={trigger => trigger.parentNode.nextSibling}
          disabledDate={current => current < validDateRange[0] || current > validDateRange[1]}
          onOpenChange={this.onOpenChange}
        ></RangePicker>
        <div className={styles.popupbox}></div>
      </div>
    );
  }
}
export default DateRangePicker;
